home *** CD-ROM | disk | FTP | other *** search
/ ADA Programming Guide / ADA Programming Guide.iso / ada_gwu / parser.c < prev    next >
C/C++ Source or Header  |  1996-01-30  |  24KB  |  927 lines

  1. /*
  2.     GWAda Development Environment for 386/486 PCs   
  3.     Copyright (C) 1993, Arthur Vargas Lopes  & Michael Bliss Feldman
  4.                         vlopes@vortex.ufrgs.br mfeldman@seas.gwu.edu
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; version 2 of the License.    
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19.  
  20. /* Parser.c */
  21.  
  22. #include "externs.h"
  23. #include "defines.h"
  24.  
  25. char *strupr(char *string);
  26. char *strcat(char *string1, const char *string2);
  27.  
  28.  
  29. typedef struct {
  30.     char yytext[AVL_MAX_LINEL + 1];
  31.     AVL_LINE_PTR temp;  /* Full source line */
  32.     int    yyleng;
  33.     int    code;
  34.     int    line_no;
  35.     int    line_col;
  36.     } TOKEN_TYPE;
  37.  
  38.  
  39. typedef struct {  /*  I/O structure  */
  40.     char        buffer[AVL_MAX_LINEL + 40];
  41.     char        last_token[AVL_MAX_LINEL + 1];
  42.     char        decimal_point;
  43.     int         size;
  44.     int         ibuf;
  45.     int         line_no;
  46.     int         look_ahead;
  47.     int         look_ahead_c[5];
  48.     int         look_ahead_t;
  49.     TOKEN_TYPE look_ahead_tcode[3];
  50.     } IO_TYPE;
  51.  
  52.  
  53.  
  54. IO_TYPE io_size;
  55.  
  56. #include "bsearch.c"
  57.  
  58.  
  59. void AVL_START_UP()
  60. {
  61.     int     ch;
  62.     char msg[100];
  63.     AVL_EDIT_WINDOW_PTR w;
  64.     w = &avl_windows[avl_window];
  65.     io_size.decimal_point     = '.';
  66.     io_size.look_ahead = 0;
  67.     io_size.line_no = w -> current_line -> line_no;
  68.     io_size.ibuf = w -> txt_col;
  69.     io_size.look_ahead_t = 0;
  70.     sprintf(io_size.buffer, w -> current_line -> line);
  71.     io_size.size = strlen(io_size.buffer);
  72.     sprintf(io_size.last_token,"THIS_IS_THE_END_OF_THE_FILE");
  73. }
  74.     
  75.  
  76. int AVL_NEXT()
  77. {
  78.     AVL_EDIT_WINDOW_PTR w;
  79.     AVL_LINE_PTR temp, temp2;
  80.     int     ch;
  81.     w = &avl_windows[avl_window];
  82.     if (io_size.look_ahead) { /* There is a look ahead char in the queue */
  83.         ch = io_size.look_ahead_c[0];
  84.         io_size.look_ahead_c[0] = io_size.look_ahead_c[1];
  85.         io_size.look_ahead_c[1] = io_size.look_ahead_c[2];
  86.         io_size.look_ahead_c[2] = io_size.look_ahead_c[3];
  87.         io_size.look_ahead_c[3] = io_size.look_ahead_c[4];
  88.         io_size.look_ahead -= 1;
  89.         return ch;
  90.         }
  91.     if (io_size.ibuf >= io_size.size)  {
  92.         if (w -> current_line -> next == w -> head)  
  93.             sprintf(io_size.buffer," \n THIS_IS_THE_END_OF_THE_FILE \" \n THIS_IS_THE_END_OF_THE_FILE  ");
  94.         else {
  95.             w -> current_line = w -> current_line -> next;
  96.             sprintf(io_size.buffer,"%s\n", w -> current_line -> line);
  97.             io_size.line_no = w -> current_line -> line_no;
  98.             }
  99.         io_size.size = strlen(io_size.buffer);
  100.         io_size.ibuf = 0;
  101.         }
  102.     ch = io_size.buffer[io_size.ibuf++];
  103.     if (ch == 26) ch = ' ';
  104.     if (ch == 0) return ' ';
  105.     return ch;
  106. }
  107.  
  108. void BACK(int     ch)
  109. {
  110.     if (io_size.look_ahead > 4)  {
  111.         AVL_ERROR("Too many look ahead bytes. SYSTEM ERROR...");
  112.         exit(1);
  113.         }
  114.     io_size.look_ahead_c[io_size.look_ahead++] = ch;
  115. }
  116.  
  117.  
  118. int IS_DIGIT(int ch, int base, int *n)  
  119. {
  120.     int     num;
  121.     char msg[40];
  122.     *n = 0;
  123.     if (ch >= 'A' && ch <= 'F')
  124.         num = ch - 'A' + 11;
  125.     else if (ch >= '0' && ch <= '9') 
  126.         num = ch - '0';
  127.     else 
  128.         return 0;
  129.     sprintf(msg,"%c in %d base ", ch, base);
  130.     if (num < 0 || num >= base)
  131.         AVL_ERROR(strcat("Based number with invalid digit ==> ",msg));
  132.     *n = num;
  133.     return 1;
  134. }
  135.  
  136. void BACK_T(TOKEN_TYPE tk)
  137. {
  138.     if (io_size.look_ahead_t > 2) {
  139.         AVL_ERROR("Too many look ahead tokens. SYSTEM ERROR...");
  140.         exit(1);
  141.         }
  142.     io_size.look_ahead_tcode[io_size.look_ahead_t++] = tk;
  143. }
  144.     
  145.  
  146. TOKEN_TYPE AVL_SCAN()
  147. {
  148.     int     ch, lch;
  149.     int     is_real = 0;
  150.     int     is_based = 0;
  151.     int     base = 10;
  152.     int     is_expo = 0;
  153.     int     string_mark;
  154.     int     temp;
  155.     static TOKEN_TYPE tk;
  156.     AVL_EDIT_WINDOW_PTR w;
  157.     char yytext[AVL_MAX_LINEL + 1];
  158.     w = &avl_windows[avl_window];
  159.  
  160.     if (io_size.look_ahead_t) {
  161.         tk = io_size.look_ahead_tcode[0];
  162.         io_size.look_ahead_tcode[0] = io_size.look_ahead_tcode[1];
  163.         io_size.look_ahead_tcode[1] = io_size.look_ahead_tcode[2];
  164.         io_size.look_ahead_t -= 1;
  165.         return tk;
  166.         }
  167.  
  168.     tk.yyleng = 0;
  169.     tk.yytext[0] = '\0';
  170. again:
  171.     /* First skip blanks */
  172.     while (isspace(ch = AVL_NEXT()));
  173.     /* Test comment */
  174.     if (ch == '-') {
  175.         ch = AVL_NEXT();
  176.         if (ch == '-') { /* Now reject til end of line */
  177.             while ((ch = AVL_NEXT()) != '\n');
  178.             goto again;
  179.             }
  180.         BACK('-');
  181.         BACK(ch);
  182.         }
  183.     else BACK(ch);
  184.     ch = AVL_NEXT();
  185.  
  186.     /* Now let's see what we got */
  187.  
  188.     tk.line_no  = io_size.line_no;
  189.     tk.line_col = io_size.ibuf;
  190.     tk.temp = w -> current_line;
  191.     if (isalpha(ch)) {  /* Got an object's name */ 
  192.         lch = ' ';
  193.         do {
  194.             if (tk.yyleng >= AVL_MAX_LINEL)  {
  195.                 tk.yytext[tk.yyleng] = '\0';
  196.                 AVL_ERROR(strcat("Symbol too long => ", tk.yytext));
  197.                 }
  198.             if (ch == '-' && lch == '-') {
  199.                 tk.yytext[tk.yyleng] = '\0';
  200.                 AVL_ERROR(strcat("Do not repeat _ ==> ", tk.yytext));
  201.                 }
  202.             tk.yytext[tk.yyleng++] = ch;
  203.             lch = ch;
  204.             ch = AVL_NEXT();
  205.             } while (isalpha(ch) || isdigit(ch) || ch == '_');
  206.         tk.yytext[tk.yyleng] = '\0';
  207.         strcpy(yytext,tk.yytext);
  208.         strupr(yytext);
  209.         if (lch == '_') 
  210.             AVL_ERROR(strcat("_ can't terminate an object's name ==> ", tk.yytext));
  211.         BACK(ch);
  212.         if (tk.code == XATTMARK) {  /* See if previous token was an ' */
  213.             lch = IS_ATT(yytext);
  214.             if (lch == 0)
  215.                 AVL_ERROR(strcat("Invalid attribute ==> ", tk.yytext));
  216.             tk.code = lch;
  217.             }
  218.         else {
  219.             if (!strcmp(yytext,"REM"))
  220.                 tk.code = XMULT;
  221.             else if (!strcmp(yytext,"MOD"))
  222.                 tk.code = XMULT;
  223.             else if (!strcmp(yytext,"AND"))
  224.                 tk.code = XLOG;
  225.             else if (!strcmp(yytext,"OR"))
  226.                 tk.code = XLOG;
  227.             else
  228.                 tk.code = IS_KEYWORD(yytext);
  229.             if (tk.code == 0)
  230.                 if (strcmp(io_size.last_token,yytext))
  231.                     tk.code = XID;
  232.             }
  233.         return tk;
  234.         }
  235.  
  236.                         
  237.     if (isdigit(ch))  {  /* Got a numeric literal */
  238.         lch = ' ';
  239.         do {
  240.             if (tk.yyleng >= AVL_MAX_LINEL)  {
  241.                 tk.yytext[tk.yyleng] = '\0';
  242.                 AVL_ERROR(strcat("Numeric literal too long ==> ", tk.yytext));
  243.                 }
  244.             if (lch == ch && ch == '_') {
  245.                 tk.yytext[tk.yyleng] = '\0';
  246.                 AVL_ERROR(strcat("Two _ repeated within numeric literal ==> ", tk.yytext));
  247.                 }
  248.             if (ch != '_')
  249.                 tk.yytext[tk.yyleng++] = ch;
  250.             lch = ch;
  251.             ch = AVL_NEXT();
  252.             } while (isdigit(ch) || ch == '_');
  253.         if (lch == '_') {
  254.             tk.yytext[tk.yyleng] = '\0';
  255.             AVL_ERROR(strcat("_ can't terminate an integer ==> ", tk.yytext));
  256.             }
  257.         if (ch == ':' || ch == '#')  { /* Got a based number */
  258.             is_based = ch;
  259.             tk.yytext[tk.yyleng] = '\0';
  260.             base = atoi(tk.yytext);
  261.             if (base < 2 || base > 16) 
  262.                 AVL_ERROR(strcat("Based literal with invalid base ==> ", tk.yytext));
  263.             tk.yyleng = 0;
  264.             ch = AVL_NEXT();
  265.             if (!IS_DIGIT(ch,base,&temp))
  266.                 AVL_ERROR("A digit was expected");
  267.             lch = ' ';
  268.             do {
  269.                 if (lch == ch && ch == '_') {
  270.                     tk.yytext[tk.yyleng] = '\0';
  271.                     AVL_ERROR(strcat("Two _ repeated within numeric literal ==> ", tk.yytext));
  272.                     }
  273.                 if (ch != '_')
  274.                     tk.yytext[tk.yyleng++] = ch;
  275.                 lch = ch;
  276.                 ch = AVL_NEXT();
  277.                 }  while (IS_DIGIT(ch,base,&temp) || ch == '_');
  278.             if (lch == '_') {
  279.                 tk.yytext[tk.yyleng] = '\0';
  280.                 AVL_ERROR(strcat("_ can't terminate an integer ==> ", tk.yytext));
  281.                 }
  282.             }
  283.         if (ch == io_size.decimal_point) { /* Got a real number? */
  284.             if (ch == '.')  {
  285.                 ch = AVL_NEXT();
  286.                 if (ch == '.')  {
  287.                     BACK('.');
  288.                     BACK('.');
  289.                     tk.yytext[tk.yyleng] = '\0';
  290.                     tk.code = XINTEGERLIT;
  291.                     return tk;
  292.                     }
  293.                 BACK(ch);
  294.                 }
  295.             is_real = 1;
  296.             tk.yytext[tk.yyleng++] = '.';
  297.             ch = AVL_NEXT();
  298.             if (!IS_DIGIT(ch,base,&temp))  {
  299.                 tk.yytext[tk.yyleng] = '\0';
  300.                 AVL_ERROR(strcat("A digit should follow a decimal point ==> ", tk.yytext));
  301.                 }
  302.             lch = ' ';
  303.             do {
  304.                 if (lch == ch && ch == '_') {
  305.                     tk.yytext[tk.yyleng] = '\0';
  306.                     AVL_ERROR(strcat("Two _ repeated within numeric literal ==> ", tk.yytext));
  307.                     }
  308.                 if (ch != '_')
  309.                     tk.yytext[tk.yyleng++] = ch;
  310.                 lch = ch;
  311.                 ch = AVL_NEXT();
  312.                 }  while (IS_DIGIT(ch,base,&temp) || ch == '_');
  313.             if (lch == '_') {
  314.                 tk.yytext[tk.yyleng] = '\0';
  315.                 AVL_ERROR(strcat("_ can't terminate an integer ==> ", tk.yytext));
  316.                 }
  317.             }
  318.         
  319.         if (is_based && is_based != ch) {
  320.             tk.yytext[tk.yyleng] = '\0';
  321.             AVL_ERROR(strcat("Missing based number delimiter ==> ", tk.yytext));
  322.             }
  323.         else if (is_based)
  324.             ch = AVL_NEXT();
  325.         if (toupper(ch) == 'E') {  /* Got an exponent */
  326.             is_expo = 1;
  327.             tk.yytext[tk.yyleng++] = ch;
  328.             ch = AVL_NEXT();
  329.             if (ch == '-' || ch == '+')  {
  330.                 if (!is_real && ch == '-')  {
  331.                     tk.yytext[tk.yyleng] = '\0';
  332.                     AVL_ERROR(strcat("E-<integer> can't be used in an integer number ==> ", tk.yytext));
  333.                     }
  334.                 tk.yytext[tk.yyleng++] = ch;
  335.                 ch = AVL_NEXT();
  336.                 }
  337.             if (!isdigit(ch))  {
  338.                 tk.yytext[tk.yyleng] = '\0';
  339.                 AVL_ERROR(strcat("A digit should follow a decimal point ==> ", tk.yytext));
  340.                 }
  341.             do {
  342.                 if (lch == ch && ch == '_') {
  343.                     tk.yytext[tk.yyleng] = '\0';
  344.                     AVL_ERROR(strcat("Two _ repeated within numeric literal ==> ", tk.yytext));
  345.                     }
  346.                 if (ch != '_')
  347.                     tk.yytext[tk.yyleng++] = ch;
  348.                 lch = ch;
  349.                 ch = AVL_NEXT();
  350.                 }  while (isdigit(ch) || ch == '_');
  351.             if (lch == '_') {
  352.                 tk.yytext[tk.yyleng] = '\0';
  353.                 AVL_ERROR(strcat("_ can't terminate an integer ==> ", tk.yytext));
  354.                 }
  355.             }
  356.         tk.yytext[tk.yyleng] = '\0';
  357.         if (is_real)
  358.             tk.code = XREALLIT;
  359.         else 
  360.             tk.code = XINTEGERLIT;
  361.         BACK(ch);
  362.         return tk;
  363.         }    /*  Done with numeric literal  */
  364.     
  365.  
  366.     switch(ch)  {
  367.  
  368.         case ':' :  {
  369.             ch = AVL_NEXT();
  370.             if (ch == '=')  {
  371.                 tk.code = XASSIGN;
  372.                 strcpy(tk.yytext,":=");
  373.                 }
  374.             else {
  375.                 BACK(ch);
  376.                 tk.code = ':';
  377.                 strcpy(tk.yytext,":");
  378.                 }
  379.             return tk;
  380.             }
  381.     
  382.         case ';' : case ',' : case '(' :
  383.         case ')' : case '|' : case '!' : case '&' : {
  384.             tk.code = ch;
  385.             if (ch == '!') ch = '|';
  386.             sprintf(tk.yytext,"%c",ch);
  387.             return(tk);
  388.             }
  389.  
  390.         case '\"' : case '%' :  {  /* Got a string */
  391.             string_mark = ch;
  392.             tk.yytext[tk.yyleng++] = ch;
  393.             while ( 1 )   {
  394.                 ch = AVL_NEXT();
  395.                 if (ch == string_mark)  {
  396.                     ch = AVL_NEXT();
  397.                     if (ch != string_mark)  { /* End of string */
  398.                         tk.yytext[tk.yyleng++] = string_mark;
  399.                         tk.yytext[tk.yyleng] = '\0';
  400.                         BACK(ch);
  401.                         tk.code = XSTRLIT;
  402.                         return tk;
  403.                         }
  404.                     }
  405.                 if (tk.yyleng >= AVL_MAX_LINEL)  {
  406.                     tk.yytext[tk.yyleng] = '\0';
  407.                     AVL_ERROR(strcat("String literal too long ==> ", tk.yytext));
  408.                     }
  409.                 if (ch == '\n')  {
  410.                     tk.yytext[tk.yyleng] = '\0';
  411.                     AVL_ERROR(strcat("String literal between lines ==> ", tk.yytext));
  412.                     }
  413.                 tk.yytext[tk.yyleng++] = ch;
  414.                 }
  415.             }
  416.  
  417.         case '+' : case '-' :  {
  418.             sprintf(tk.yytext,"%c",ch);
  419.             tk.code = XARIT;
  420.             return tk;
  421.             }
  422.  
  423.         case '/' :  {
  424.             ch = AVL_NEXT();
  425.             if (ch != '=')   {
  426.                 tk.code = XMULT;
  427.                 strcpy(tk.yytext,"/");
  428.                 return tk;
  429.                 }
  430.             sprintf(tk.yytext,"/=");
  431.             tk.code = XREL;
  432.             return tk;
  433.             }
  434.  
  435.         case '*' : {
  436.             ch = AVL_NEXT();
  437.             if (ch != '*')  
  438.                 BACK(ch);
  439.             else {
  440.                 strcpy(tk.yytext,"**");
  441.                 tk.code = XEXP;
  442.                 return tk;
  443.                 }
  444.             ch = '*';
  445.             sprintf(tk.yytext,"%c",ch);
  446.             tk.code = XMULT;
  447.             return tk;
  448.             }
  449.  
  450.         case '.' :  {
  451.             ch = AVL_NEXT();
  452.             if (ch == '.')  {
  453.                 strcpy(tk.yytext,"..");
  454.                 tk.code = XDOTDOT;
  455.                 return tk;
  456.                 }
  457.             BACK(ch);
  458.             strcpy(tk.yytext,".");
  459.             tk.code = '.';
  460.             return tk;
  461.             }
  462.  
  463.         case '\'' :   {  /* Got an attribute ?  */
  464.             ch = AVL_NEXT();
  465.             lch = AVL_NEXT();
  466.             if (lch == '\'') { /* Got a character literal!  */
  467.                 sprintf(tk.yytext,"%c",ch);
  468.                 tk.code = XCHARLIT;
  469.                 return tk;
  470.                 }
  471.             tk.code = XATTMARK;
  472.             strcpy(tk.yytext,"'");
  473.             BACK(lch);
  474.             BACK(ch);
  475.             return tk;
  476.             }
  477.  
  478.         case '=' : {
  479.             ch = AVL_NEXT();
  480.             if (ch == '>')  {
  481.                 strcpy(tk.yytext,"=>");
  482.                 tk.code = XEQGT;
  483.                 }
  484.             else 
  485.                 BACK(ch);
  486.             strcpy(tk.yytext,"=");
  487.             tk.code = XREL;
  488.             return tk;
  489.             }
  490.  
  491.         case '>' : case '<' : {
  492.             if (ch == '<')  {
  493.                 int k;
  494.                 k = ch;
  495.                 ch = AVL_NEXT();
  496.                 if (ch == '>')  {
  497.                     strcpy(tk.yytext,"<>");
  498.                     tk.code = XLTGT;
  499.                     return tk;
  500.                     }
  501.                 BACK(ch);
  502.                 ch = k;
  503.                 }
  504.             tk.code = XREL;
  505.             tk.yytext[0] = ch;
  506.             tk.yytext[1] = '\0';
  507.             tk.yytext[2] = '\0';
  508.             ch = AVL_NEXT();
  509.             if (ch == '=')  
  510.                 tk.yytext[1] = ch;
  511.             else
  512.                 BACK(ch);
  513.             return tk;
  514.             }
  515.                                 
  516.         default : {
  517.             sprintf(tk.yytext,"[decimal=%d]",ch);
  518.             AVL_ERROR(strcat("Invalid character ==> ", tk.yytext));
  519.             }
  520.         }
  521. }
  522.  
  523.  
  524. int IS_SIMPLE(char *s)
  525. {
  526.     if (!strcmp(s,"TEXT_IO")) return 0;
  527.     if (!strcmp(s,"ASCII")) return 0;
  528.     if (!strcmp(s,"STANDARD")) return 0;
  529.     if (!strcmp(s,"CALENDAR")) return 0;
  530.     if (!strcmp(s,"SYSTEM")) return 0;
  531.     if (!strcmp(s,"MACHINE_CODE")) return 0;
  532.     if (!strcmp(s,"IO_EXCEPTIONS")) return 0;
  533.     if (!strcmp(s,"LOW_LEVEL_IO")) return 0;
  534.     return 1;
  535. }
  536.  
  537. int pos_p = 0;
  538. int AVL_Append_In_Text;
  539. static AVL_EDIT_WINDOW AVL_Parsing, AVL_Appending;
  540. static int AVL_Parser_Pos = 1, AVL_Parser_Line = -100;
  541.  
  542. void AVL_OUT_BODY(FILE *fp, TOKEN_TYPE tk)
  543. {
  544.     int i;
  545.     AVL_Parsing = avl_windows[avl_window];
  546.     if (AVL_Parser_Line == -100) {
  547.         AVL_Parser_Line = tk.line_no;
  548.         AVL_Parser_Pos = 1;
  549.         if (AVL_Append_In_Text)  {
  550.             /* Go to last line of current text */
  551.             AVL_DO_GOTO(AVL_Parsing.head -> previous -> line_no);
  552.             AVL_CURSOR_END();
  553.             AVL_EDIT_ENTER(); /* Insert a blank line */
  554.             AVL_EDIT_ENTER(); /* Insert a blank line */
  555.             AVL_Appending = avl_windows[avl_window];        
  556.             }
  557.         }
  558.     if (AVL_Parser_Line != tk.line_no)  {
  559.         AVL_Parser_Pos = 1; 
  560.         AVL_Parser_Line = tk.line_no; 
  561.         if (AVL_Append_In_Text == 0)
  562.             fprintf(fp,"\n"); 
  563.         else {
  564.             avl_windows[avl_window] = AVL_Appending;
  565.             AVL_CURSOR_END();
  566.             AVL_EDIT_ENTER(); /* Insert a blank line */
  567.             avl_windows[avl_window].txt_col = 0;
  568.             AVL_Appending = avl_windows[avl_window];        
  569.             }
  570.         }
  571.     if (pos_p) {
  572.         AVL_Parser_Pos = 1;
  573.         tk.line_col = pos_p;
  574.         }
  575.     avl_windows[avl_window] = AVL_Appending;
  576.     for( ; AVL_Parser_Pos < tk.line_col; ++AVL_Parser_Pos) {
  577.         if (AVL_Append_In_Text == 0)
  578.             fprintf(fp," ");
  579.         else 
  580.             AVL_EDIT_INSERT(' ');
  581.         }
  582.     AVL_Appending = avl_windows[avl_window];        
  583.     if (AVL_Append_In_Text == 0)
  584.         fprintf(fp,"%s", tk.yytext);
  585.     else {
  586.         avl_windows[avl_window] = AVL_Appending;
  587.         for(i=0; i < strlen(tk.yytext); ++i)
  588.             if (tk.yytext[i] == '\n')  {
  589.                 AVL_CURSOR_END();
  590.                 AVL_EDIT_ENTER();
  591.                 }
  592.             else
  593.                 AVL_EDIT_INSERT(tk.yytext[i]);
  594.         AVL_Appending = avl_windows[avl_window];        
  595.         }
  596.     avl_windows[avl_window] = AVL_Parsing;
  597.     AVL_Parser_Pos += strlen(tk.yytext);
  598. }
  599.  
  600. void AVL_SKIP_RECORD()
  601. {
  602.     TOKEN_TYPE tk;
  603.     tk = AVL_SCAN();
  604.     while ( tk.code != 0 )  {
  605.         if (tk.code == XRECORD) AVL_SKIP_RECORD();
  606.         else if (tk.code == XEND)  {
  607.             tk = AVL_SCAN();
  608.             if (tk.code == XRECORD) return;
  609.             else if (tk.code == XCASE) tk = AVL_SCAN();
  610.             else {
  611.                 AVL_ERROR("First make sure the package spec is correct.");
  612.                 tk.code = 0;
  613.                 BACK_T(tk);
  614.                 return;
  615.                 }
  616.             }
  617.         if (tk.code == XPROCEDURE || tk.code == XFUNCTION || tk.code == XTASK)  {
  618.             tk.code = 0;
  619.             BACK_T(tk);
  620.             return;
  621.             }
  622.         tk = AVL_SCAN();
  623.         }
  624. }
  625.  
  626. int AVL_FAIL(FILE *fp)            
  627. {
  628.     fclose(fp);
  629.     AVL_ERROR("Syntax error within package spec.");
  630.     return -1;
  631. }
  632.  
  633. int AVL_PARSER()
  634. {
  635.     TOKEN_TYPE tk, tk2, tk3, tk4, tk5, tk6;
  636.     static int first = 0;
  637.     static char fname[161];
  638.     static char lastfn[121];
  639.     static char *msg = " GWAda - Create Body in File? ";
  640.     char msg2[161];
  641.     AVL_WIN_PTR m = NULL;
  642.     int nt = 0;
  643.     int i, j, code;
  644.     short with_entry = 0;
  645.     AVL_EDIT_WINDOW_PTR w;
  646.     AVL_LINE_PTR temp, temp2;
  647.     FILE *fopen(), *fp = NULL;
  648.     w = &avl_windows[avl_window];
  649.     pos_p = 0;
  650.     AVL_START_UP();
  651.  
  652.     tk = AVL_SCAN();
  653.     if (tk.code != XPACKAGE)
  654.         tk = AVL_SCAN();
  655.     switch(tk.code)  {
  656.         case XPACKAGE :  /* Where packages are defined? */
  657.             tk2 = AVL_SCAN(); /* got package's name */
  658.             if (tk2.code == XBODY) 
  659.                 break;
  660.             tk3 = AVL_SCAN();  /* got is? */
  661.             if (tk3.code != XIS)     
  662.                 break;
  663.             tk4 = AVL_SCAN();
  664.             if (tk4.code == XNEW) 
  665.                 return 0;
  666.             tk6 = tk2;
  667.             /* Got a package speck */
  668.             sprintf(msg2,"Append the template at the end of this file (Y/N) ? ");
  669.             if (AVL_QUESTION(msg2) == 'Y')  
  670.                 AVL_Append_In_Text = 1;
  671.             else {
  672.                 AVL_Append_In_Text = 0;
  673.                 /* Now ask for a package body name */
  674.                 m = AVL_MAKE_WINDOW(msg,7,4,9,5+62,avl_wnd_bk_color,avl_wnd_color);
  675.                 if (first == 0)
  676.                     sprintf(lastfn,"%s%c*.ada",avl_dir_sources,92);
  677.                 first = 1;
  678.                 strcpy(fname,lastfn);
  679.                 if (AVL_PROMPT(1,1,fname,60)) {
  680.                     AVL_DEL_WINDOW(m);
  681.                     return -1;
  682.                     }
  683.                 strcpy(lastfn,fname);
  684.                 if ((fp = fopen(fname,"r")) != NULL)  {
  685.                     sprintf(msg2,"File %s already exists. Overwrite (Y/N) ? ", fname);
  686.                     if (AVL_QUESTION(msg2) != 'Y')  {
  687.                         AVL_DEL_WINDOW(m);
  688.                         return -1;
  689.                         }
  690.                     fclose(fp);
  691.                     unlink(fname);
  692.                     }
  693.                 fp = fopen(fname,"w");
  694.                 if (fp == NULL)  {
  695.                     sprintf(msg2,"Can't create file %s", fname);
  696.                     AVL_ERROR(msg2);
  697.                     AVL_DEL_WINDOW(m);
  698.                     return -1;
  699.                     }
  700.                 }
  701.             AVL_OUT_BODY(fp,tk); /* Output PACKAGE in the correct text position */            
  702.             strcpy(tk.yytext," BODY "); AVL_OUT_BODY(fp,tk); 
  703.             AVL_OUT_BODY(fp,tk2); /* Output PACKAGE name */            
  704.             strcpy(tk.yytext," IS\n"); 
  705.             AVL_OUT_BODY(fp,tk); 
  706.             while ( tk4.code != 0 )  {
  707.                 switch( tk4.code ) {
  708.                     case XTASK      : {
  709.                         tk5 = tk4;
  710.                         with_entry = 0;
  711.                         AVL_OUT_BODY(fp,tk4);
  712.                         strcpy(tk4.yytext," BODY ");
  713.                         AVL_OUT_BODY(fp,tk4);
  714.                         tk2 = AVL_SCAN(); /* tk2 hold the task's name */
  715.                         if (tk2.code == 0) return AVL_FAIL(fp);
  716.                         if (tk2.code == XTYPE) {
  717.                             tk2 = AVL_SCAN();
  718.                             if (tk2.code == 0) return AVL_FAIL(fp);
  719.                             }
  720.                         AVL_OUT_BODY(fp,tk2);
  721.                         tk3 = tk2;
  722.                         strcpy(tk3.yytext," IS");
  723.                         AVL_OUT_BODY(fp,tk3);
  724.                         strcpy(tk5.yytext,"BEGIN");
  725.                         tk5.line_no = 0;
  726.                         AVL_OUT_BODY(fp,tk5);
  727.                         tk3 = AVL_SCAN(); 
  728.                         if (tk3.code == 0) return AVL_FAIL(fp);
  729.                         if (tk3.code == ';')  {
  730.                             tk6 = tk5;
  731.                             tk6.line_no += 1;
  732.                             tk6.line_col += avl_tab_size;
  733.                             sprintf(tk6.yytext,"NULL;");
  734.                             AVL_OUT_BODY(fp,tk6);
  735.                             tk6.line_no += 1;
  736.                             tk6.line_col -= avl_tab_size;
  737.                             sprintf(tk6.yytext,"END %s;\n",tk2.yytext);
  738.                             AVL_OUT_BODY(fp,tk6);
  739.                             break;
  740.                             }
  741.  
  742.                         tk3 = AVL_SCAN(); 
  743.                         if (tk3.code == 0) return AVL_FAIL(fp);
  744.                         while (tk3.code == XENTRY)  {
  745.                             tk6 = tk3;
  746.                             with_entry = 1;
  747.                             strcpy(tk3.yytext,"ACCEPT ");
  748.                             AVL_OUT_BODY(fp,tk3);
  749.                             tk4 = AVL_SCAN();
  750.                             if (tk4.code == 0) return AVL_FAIL(fp);
  751.                             AVL_OUT_BODY(fp,tk4);  /* output entry name */
  752.                             tk3 = AVL_SCAN();
  753.                             if (tk3.code == ';')  {
  754.                                 AVL_OUT_BODY(fp,tk3); 
  755.                                 tk3 = AVL_SCAN();
  756.                                 continue;
  757.                                 }
  758.                             if (tk3.code == '(')  {
  759.                                 while (tk3.code != ')')  {
  760.                                     if (tk3.code == 0) return AVL_FAIL(fp);
  761.                                     tk.line_col += 1;
  762.                                     AVL_OUT_BODY(fp,tk3); 
  763.                                     tk3 = AVL_SCAN();
  764.                                     }
  765.                                 AVL_OUT_BODY(fp,tk3); 
  766.                                 tk3 = AVL_SCAN();
  767.                                 }
  768.                             tk5 = tk3;
  769.                             strcpy(tk5.yytext," DO");
  770.                             AVL_OUT_BODY(fp,tk5);
  771.                             tk6.line_no = 0;
  772.                             tk6.line_col += avl_tab_size;
  773.                             sprintf(tk6.yytext,"NULL;");
  774.                             AVL_OUT_BODY(fp,tk6);
  775.                             tk6.line_no += 1;
  776.                             tk6.line_col -= avl_tab_size;
  777.                             sprintf(tk6.yytext,"END %s;",tk4.yytext);
  778.                             AVL_OUT_BODY(fp,tk6);
  779.                             tk3 = AVL_SCAN();
  780.                             }
  781.                         while (tk3.code != XEND) {
  782.                             if (tk3.code == 0) return AVL_FAIL(fp);
  783.                             tk3 = AVL_SCAN();
  784.                             }
  785.                         if (!with_entry)  {
  786.                             tk4 = tk3;
  787.                             tk4.line_no = 0;
  788.                             tk4.line_col += avl_tab_size;
  789.                             sprintf(tk4.yytext,"NULL;");
  790.                             AVL_OUT_BODY(fp,tk4);
  791.                             }
  792.                         sprintf(tk3.yytext,"END %s;\n",tk2.yytext);
  793.                         AVL_OUT_BODY(fp,tk3);
  794.                         break;
  795.                         }
  796.                     case XPROCEDURE :
  797.                     case XFUNCTION  :  {
  798.                         AVL_OUT_BODY(fp,tk4);
  799.                         tk2 = AVL_SCAN(); /* tk2 hold the routine's name */
  800.                         if (tk2.code == 0) return AVL_FAIL(fp);
  801.                         AVL_OUT_BODY(fp,tk2);
  802.                         tk3 = AVL_SCAN(); 
  803.                         if (tk3.code == 0) return AVL_FAIL(fp);
  804.                         if (tk3.code == '(')  {
  805.                             AVL_OUT_BODY(fp,tk3);
  806.                             tk3 = AVL_SCAN();
  807. /*                            pos_p = tk3.line_col;   */
  808.                             while (tk3.code != ')')  {
  809.                                 if (tk3.code == 0) return AVL_FAIL(fp);
  810. /*                                tk3.line_col = pos_p;   */
  811.                                 AVL_OUT_BODY(fp,tk3); 
  812.                                 tk3 = AVL_SCAN();
  813.                                 }
  814.                             AVL_OUT_BODY(fp,tk3); 
  815.                             tk3 = AVL_SCAN();
  816.                             }
  817.                         if (tk3.code == 0) return AVL_FAIL(fp);
  818.                         if (tk3.code == XRETURN)  {
  819.                             AVL_OUT_BODY(fp,tk3);
  820.                             tk3 = AVL_SCAN();
  821.                             if (tk3.code == 0) return AVL_FAIL(fp);
  822.                             AVL_OUT_BODY(fp,tk3);
  823.                             tk5 = tk3;
  824.                             strcpy(tk5.yytext," IS");
  825.                             AVL_OUT_BODY(fp,tk5);
  826.                             tk4.line_no = 0;
  827.                             tk4.line_col += avl_tab_size;
  828.                             sprintf(tk4.yytext,"Result : %s;",tk3.yytext); 
  829.                             AVL_OUT_BODY(fp,tk4);
  830.                             strcpy(tk4.yytext,"BEGIN"); 
  831.                             tk4.line_no += 1;
  832.                             tk4.line_col -= avl_tab_size;
  833.                             AVL_OUT_BODY(fp,tk4);
  834.                             tk4.line_no += 1;
  835.                             tk4.line_col += avl_tab_size;
  836.                             sprintf(tk4.yytext,"RETURN Result;");
  837.                             AVL_OUT_BODY(fp,tk4);
  838.                             }
  839.                         else {
  840.                             tk5 = tk3;
  841.                             strcpy(tk5.yytext," IS");
  842.                             AVL_OUT_BODY(fp,tk5);
  843.                             tk4.line_no = 0;
  844.                             strcpy(tk4.yytext,"BEGIN"); 
  845.                             AVL_OUT_BODY(fp,tk4);
  846.                             tk4.line_no += 1;
  847.                             tk4.line_col += avl_tab_size;
  848.                             sprintf(tk4.yytext,"NULL;");
  849.                             AVL_OUT_BODY(fp,tk4);
  850.                             }
  851.                         sprintf(tk4.yytext,"END %s;\n",tk2.yytext);
  852.                         tk4.line_no += 1;
  853.                         tk4.line_col -= avl_tab_size;
  854.                         AVL_OUT_BODY(fp,tk4);
  855.                         break;
  856.                         }
  857.                     case XRECORD :
  858.                         AVL_SKIP_RECORD();
  859.                         break;
  860.                     case XEND    :
  861.                         AVL_OUT_BODY(fp,tk4);
  862.                         tk = AVL_SCAN();
  863.                         if (tk.code == 0) return AVL_FAIL(fp);
  864.                         if (tk.code != ';') {
  865.                             AVL_OUT_BODY(fp,tk);
  866.                             tk = AVL_SCAN();
  867.                             }
  868.                         if (tk.code == 0) return AVL_FAIL(fp);
  869.                         AVL_OUT_BODY(fp,tk);
  870.                         if (AVL_Append_In_Text == 0)  {
  871.                             fprintf(fp,"\n");
  872.                             fclose(fp);
  873.                             }
  874.                         else {
  875.                             AVL_Parsing = avl_windows[avl_window];        
  876.                             avl_windows[avl_window] = AVL_Appending;
  877.                             AVL_EDIT_ENTER();
  878.                             AVL_Appending = avl_windows[avl_window];        
  879.                             avl_windows[avl_window] = AVL_Parsing;
  880.                             }
  881.  
  882.                         fp = NULL;
  883.                         AVL_DEL_WINDOW(m);
  884.                         return 1;
  885.                     default :
  886.                         break;
  887.                     }
  888.                 tk4 = AVL_SCAN();
  889.                 }
  890.         default :
  891.             break;
  892.         }
  893.     if (fp != NULL)
  894.         AVL_ERROR("Invalid syntax for package spec.");
  895.     sprintf(tk4.yytext,"END;");
  896.     tk4.line_no += 1000;
  897.     tk4.line_col = 1;
  898.     AVL_OUT_BODY(fp,tk4);
  899.     AVL_DEL_WINDOW(m);
  900.     return 0;
  901. }    
  902.  
  903. void AVL_BODY()
  904. {
  905.     AVL_EDIT_WINDOW_PTR w;
  906.     int old_txt;
  907.     AVL_LINE_PTR temp, temp2;
  908.     w = &avl_windows[avl_window];
  909.     AVL_Appending = avl_windows[avl_window];
  910.     AVL_Parser_Pos = 1;
  911.     AVL_Parser_Line = -100;
  912.     old_txt = w -> txt_col;
  913.     temp = w -> current_line;
  914.     AVL_WORD_BACKWARD();
  915.     if (!AVL_PARSER())
  916.         AVL_ERROR("Press F7 only when the cursor is over a valid PACKAGE spec.");
  917.     if (AVL_Append_In_Text)  {
  918.         avl_windows[avl_window] = AVL_Appending;
  919.         AVL_UPDATE_SCREEN();
  920.         }
  921.     else {
  922.         w -> current_line = temp;
  923.         w -> txt_col = old_txt;
  924.         }
  925. }
  926.  
  927.